package com.example.blog.service.impl;

import com.alibaba.fastjson.JSON;
import com.example.blog.dao.pojo.User;
import com.example.blog.service.LoginService;
import com.example.blog.service.UserService;
import com.example.blog.utils.JWTUtils;
import com.example.blog.vo.Result;
import com.example.blog.vo.params.LoginParams;
import io.netty.util.internal.StringUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Transactional

public class LoginServiceImpl implements LoginService {
    private static final String salt = "#@!huamiaoyi!@$$";
    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public Result login(LoginParams loginParams) {
        /**
         * 1、检查参数是否合法
         * 2、根据用户名查找用户名和密码在表中是否存在
         * 3、如果不存在 登录失败
         * 4、登录成功使用jwt生成token返回给前端佬
         * 5、token放入redis中， redis token：信息  设置过期时间
         * （登录认证时 先认证token是否合法 再去redis严重是否存在）
         */
        String account = loginParams.getAccount();
        String password = loginParams.getPassword();
        if(StringUtils.isBlank(account) || StringUtils.isBlank(password)){
            return Result.fail(-100,"用户名和密码不能为空");
        }

        password = DigestUtils.md5Hex(password + salt);
        System.out.println("账号"+account+"密码"+password);
        User user = userService.findUser(account,password);
        if (user == null){
            return Result.fail(-100,"用户名或密码错误");
        }
        String token = JWTUtils.createToken(user.getId());
        redisTemplate.opsForValue().set(token, JSON.toJSONString(user),3, TimeUnit.HOURS);
        return Result.success(token);
    }

    @Override
    public User checkToken(String token) {
        if (token.equals("Bearer null")) {
            return null;
        }
        token = token.substring(7);
        Map<String, Object> stringObjectMap = JWTUtils.checkToken(token);
        if (stringObjectMap == null){
            return null;
        }

        String userJson = redisTemplate.opsForValue().get(token);
        if (StringUtils.isBlank(userJson)){
            return null;
        }
        User user = JSON.parseObject(userJson, User.class);
        return user;
    }

    @Override
    public Result logout(String token) {
        redisTemplate.delete(token.substring(7));
        return Result.success(token);
    }


    /**
     * 1、参数合法性
     * 2、账户是否存在
     * 3、注册用户时 生成token
     * 4、将token存入redis中
     * 注意加上失物，一旦中间的任何过程出现问题，事务回滚
     */
    @Override
    public Result register(LoginParams loginParams) {

        String account = loginParams.getAccount();
        String nickname = loginParams.getNickname();
        String password = loginParams.getPassword();
        if (StringUtils.isBlank(account) || StringUtils.isBlank(nickname) || StringUtils.isBlank(password)){
            return Result.fail(-1000,"请输入完整的注册信息");
        }
        User user = userService.findUserByAccount(account);
        if (user != null){
            return Result.fail(-1000,"用户已存在");
        }
        user = new User();
        user.setAccount(account);
        user.setNickname(nickname);
        user.setPassword(DigestUtils.md5Hex(password+salt));
        user.setAvatar("http:huamiaoyi.xyz/img/default.jpg");
        Date date = new Date();
        user.setCreateTime(date);
        userService.save(user);

        String token = JWTUtils.createToken(user.getId());

        redisTemplate.opsForValue().set(token, JSON.toJSONString(user),3, TimeUnit.HOURS);
        return Result.success(token);
    }
}
